
import { removeArr, on } from './util';

const routers = new Map();

/**
 * 添加路由匹配, 页面已加载也是会触发
 * @param urlRegex 使用 相对路径+查询参数 进行匹配,如:"/a/b.c?d=1&e=2"
 * @param cb (url, query)=>void  query为查询参数的对象化
*/
export function onRoute(urlRegex, cb) {
    let cbList = routers.get(urlRegex);
    if (!cbList) cbList = [];
    cbList.push(cb);
    routers.set(urlRegex, cbList);
}
export function offRoute(urlRegex, cb) {
    let cbList = routers.get(urlRegex);
    if (!cbList) return true;
    removeArr(cbList, c => c === cb);
    routers.set(urlRegex, cbList);
    return true;
}
/**
 * 路由到一个地址(地址变更但页面不跳转), 触发对应的路由
*/
export function routeUrl(url) {
    history.pushState(null, null, url);
    emitRouterUrl(url);
}

function parseQuery2Obj(urlquery) {
    var query = Object.create(null);
    if (!urlquery) return query;
    if (urlquery.startsWith('?')) urlquery = urlquery.substr(1);
    let qs = urlquery.split('&');
    for (let nv of qs) {
        var dINdex = nv.indexOf('=');
        if (dINdex > -1) {
            query[decodeURIComponent(nv.substr(0, dINdex))] = decodeURIComponent(nv.substr(dINdex + 1));
        } else {
            query[nv] = '';
        }
    }
    return query;
}

function emitRouterUrl(url) {
    var r = url.matchAll(/^(http[s]\:\/\/[^\/]+)?(\/[^\?]*)(\?.*)?$/ig)
    if (!r) return false;
    var m = r[0];
    if (!m || m.length !== 4) return false;
    var urpath = m[2];
    var urlquery = m[3];
    return emitRouter(urpath, urlquery);
}
function emitRouter(urlpath, urlquery) {
    var url = urlpath + urlquery;
    var query = parseQuery2Obj(urlquery);
    var hasMatch = false;
    for (let [urlRegex, routeArr] of routers) {
        if (url.match(urlRegex)) {
            hasMatch = true;
            for (let cb of routeArr) {
                cb(url, query);
            }
        }
    }
    return hasMatch;
}


/**
 * 初始化路由器(入口等页面加载完,或所有模块加载完,统一调用, 即需要在路由都注册完后调用)
*/
export function initRouter() {
    on(window, ['popstate'], function (e) {
        emitRouter(window.location.pathname, window.location.search);
    });
    //初始触发一次
    emitRouter(window.location.pathname, window.location.search);
}